home *** CD-ROM | disk | FTP | other *** search
/ Software of the Month Club 2000 October / Software of the Month - Ultimate Collection Shareware 277.iso / pc / PROGRAMS / UTILITY / WINLINUX / DATA1.CAB / programs_-_include / ASM-M68K / CHECKSUM.H < prev    next >
C/C++ Source or Header  |  1999-09-17  |  4KB  |  155 lines

  1. #ifndef _M68K_CHECKSUM_H
  2. #define _M68K_CHECKSUM_H
  3.  
  4. /*
  5.  * computes the checksum of a memory block at buff, length len,
  6.  * and adds in "sum" (32-bit)
  7.  *
  8.  * returns a 32-bit number suitable for feeding into itself
  9.  * or csum_tcpudp_magic
  10.  *
  11.  * this function must be called with even lengths, except
  12.  * for the last fragment, which may be odd
  13.  *
  14.  * it's best to have buff aligned on a 32-bit boundary
  15.  */
  16. unsigned int csum_partial(const unsigned char * buff, int len, unsigned int sum);
  17.  
  18. /*
  19.  * the same as csum_partial, but copies from src while it
  20.  * checksums
  21.  *
  22.  * here even more important to align src and dst on a 32-bit (or even
  23.  * better 64-bit) boundary
  24.  */
  25.  
  26. unsigned int csum_partial_copy(const char *src, char *dst, int len, int sum);
  27.  
  28.  
  29. /*
  30.  * the same as csum_partial_copy, but copies from user space.
  31.  *
  32.  * here even more important to align src and dst on a 32-bit (or even
  33.  * better 64-bit) boundary
  34.  */
  35.  
  36. extern unsigned int csum_partial_copy_from_user(const char *src, char *dst,
  37.                         int len, int sum, int *csum_err);
  38.  
  39. #define csum_partial_copy_nocheck(src, dst, len, sum)    \
  40.     csum_partial_copy((src), (dst), (len), (sum))
  41.  
  42. /*
  43.  *    This is a version of ip_compute_csum() optimized for IP headers,
  44.  *    which always checksum on 4 octet boundaries.
  45.  *
  46.  */
  47. static inline unsigned short
  48. ip_fast_csum(unsigned char *iph, unsigned int ihl)
  49. {
  50.     unsigned int sum = 0;
  51.  
  52.     __asm__ ("subqw #1,%2\n"
  53.          "1:\t"
  54.          "movel %1@+,%/d0\n\t"
  55.          "addxl %/d0,%0\n\t"
  56.          "dbra  %2,1b\n\t"
  57.          "movel %0,%/d0\n\t"
  58.          "swap  %/d0\n\t"
  59.          "addxw %/d0,%0\n\t"
  60.          "clrw  %/d0\n\t"
  61.          "addxw %/d0,%0\n\t"
  62.          : "=d" (sum), "=a" (iph), "=d" (ihl)
  63.          : "0" (sum), "1" (iph), "2" (ihl)
  64.          : "d0");
  65.     return ~sum;
  66. }
  67.  
  68. /*
  69.  *    Fold a partial checksum
  70.  */
  71.  
  72. static inline unsigned int csum_fold(unsigned int sum)
  73. {
  74.     unsigned int tmp = sum;
  75.     __asm__("swap %1\n\t"
  76.         "addw %1, %0\n\t"
  77.         "clrw %1\n\t"
  78.         "addxw %1, %0"
  79.         : "=&d" (sum), "=&d" (tmp)
  80.         : "0" (sum), "1" (sum));
  81.     return ~sum;
  82. }
  83.  
  84.  
  85. /*
  86.  * computes the checksum of the TCP/UDP pseudo-header
  87.  * returns a 16-bit checksum, already complemented
  88.  */
  89.  
  90. static inline unsigned int
  91. csum_tcpudp_nofold(unsigned long saddr, unsigned long daddr, unsigned short len,
  92.           unsigned short proto, unsigned int sum)
  93. {
  94.     __asm__ ("addl  %1,%0\n\t"
  95.          "addxl %4,%0\n\t"
  96.          "addxl %5,%0\n\t"
  97.          "clrl %1\n\t"
  98.          "addxl %1,%0"
  99.          : "=&d" (sum), "=&d" (saddr)
  100.          : "0" (daddr), "1" (saddr), "d" (len + proto),
  101.            "d"(sum));
  102.     return sum;
  103. }
  104.  
  105. static inline unsigned short int
  106. csum_tcpudp_magic(unsigned long saddr, unsigned long daddr, unsigned short len,
  107.           unsigned short proto, unsigned int sum)
  108. {
  109.     return csum_fold(csum_tcpudp_nofold(saddr,daddr,len,proto,sum));
  110. }
  111.  
  112. /*
  113.  * this routine is used for miscellaneous IP-like checksums, mainly
  114.  * in icmp.c
  115.  */
  116.  
  117. static inline unsigned short
  118. ip_compute_csum(unsigned char * buff, int len)
  119. {
  120.     return csum_fold (csum_partial(buff, len, 0));
  121. }
  122.  
  123. #define _HAVE_ARCH_IPV6_CSUM
  124. static __inline__ unsigned short int
  125. csum_ipv6_magic(struct in6_addr *saddr, struct in6_addr *daddr,
  126.         __u16 len, unsigned short proto, unsigned int sum) 
  127. {
  128.     register unsigned long tmp;
  129.     __asm__("addl %2@,%0\n\t"
  130.         "movel %2@(4),%1\n\t"
  131.         "addxl %1,%0\n\t"
  132.         "movel %2@(8),%1\n\t"
  133.         "addxl %1,%0\n\t"
  134.         "movel %2@(12),%1\n\t"
  135.         "addxl %1,%0\n\t"
  136.         "movel %3@,%1\n\t"
  137.         "addxl %1,%0\n\t"
  138.         "movel %3@(4),%1\n\t"
  139.         "addxl %1,%0\n\t"
  140.         "movel %3@(8),%1\n\t"
  141.         "addxl %1,%0\n\t"
  142.         "movel %3@(12),%1\n\t"
  143.         "addxl %1,%0\n\t"
  144.         "addxl %4,%0\n\t"
  145.         "clrl %1\n\t"
  146.         "addxl %1,%0"
  147.         : "=&d" (sum), "=&d" (tmp)
  148.         : "a" (saddr), "a" (daddr), "d" ((__u32) len + proto),
  149.           "0" (sum));
  150.  
  151.     return csum_fold(sum);
  152. }
  153.  
  154. #endif /* _M68K_CHECKSUM_H */
  155.